<template>
   <el-card style="height: 80px;">
      <el-form inline class="form">
         <el-form-item label="职位名称">
            <el-input placeholder="请输入职位名称" v-model="keyword"></el-input>
         </el-form-item>
         <el-form-item>
            <el-button type="primary" :disabled="keyword ? false : true" @click="search">搜索</el-button>
            <el-button @click="reset">重置</el-button>
         </el-form-item>
      </el-form>
   </el-card>
   <el-card style="margin: 10px 0;">
      <el-button type="primary" icon="Plus" @click="addRole">添加职位</el-button>
      <!-- 展示数据 -->
      <el-table border style="margin: 10px 0;" :data="allRoleArr">
         <el-table-column label="#" align="center" type="index"></el-table-column>
         <el-table-column label="ID" align="center" prop="id"></el-table-column>
         <el-table-column label="角色名称" align="center" prop="roleName" show-overflow-tooltip></el-table-column>
         <el-table-column label="创建时间" align="center" prop="createTime" show-overflow-tooltip></el-table-column>
         <el-table-column label="更新时间" align="center" prop="updateTime" show-overflow-tooltip></el-table-column>
         <el-table-column label="操作" align="center" width="400px">
            <!-- row:已有的职位对象 -->
            <template #="{ row, $index }">
               <el-button type="primary" icon="User" size="small" @click="setPermission(row)">分配权限</el-button>
               <el-button type="primary" icon="Edit" size="small" @click="updateRole(row)">编辑</el-button>
               <el-popconfirm :title="`你确定要删除${row.roleName}？`" @confirm="deleteRole(row.id)" width="260px">
                  <template #reference>
                     <el-button type="primary" icon="Delete" size="small">删除</el-button>
                  </template>
               </el-popconfirm>
            </template>
         </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <el-pagination v-model:current-page="pageNo" v-model:page-size="pageSize" :page-sizes="[10, 20, 30, 40]"
         :background="true" layout="prev, pager, next, jumper,->,sizes,total" :total="total" @current-change="getAllRole"
         @size-change="sizeChange" />
   </el-card>
   <!-- 对话框：添加职位|更新已有职位信息 -->
   <el-dialog v-model="dialogVisible" :title="roleParams.id ? '更新职位' : '添加职位'">
      <el-form :model="roleParams" :rules="rules" ref="form">
         <el-form-item label="职位名称" prop="roleName">
            <el-input placeholder="请你输入职位的名称" v-model="roleParams.roleName"></el-input>
         </el-form-item>
      </el-form>
      <template #footer>
         <el-button @click="dialogVisible = false">取消</el-button>
         <el-button type="primary" @click="save">确定</el-button>
      </template>
   </el-dialog>
   <!-- 抽屉：分配职位的权限 -->
   <el-drawer v-model="drawer">
      <template #header>
         <h4>分配权限</h4>
      </template>
      <template #default>
         <!-- 树形控件 -->
         <el-tree ref="tree" :data="menuArr" show-checkbox node-key="id" default-expand-all
            :default-checked-keys="selectArr" :props="defaultProps" />
      </template>
      <template #footer>
         <el-button @click="drawer = false">取消</el-button>
         <el-button type="primary" @click="confirm">确定</el-button>
      </template>
   </el-drawer>
</template>

<script setup lang="ts">
import { nextTick, onMounted, reactive, ref } from 'vue'
import { reqAllRoleList, reqAddOrUpdateRole, reqAllMenuList, reqSetPermission, reqDeleteRole } from '@/api/acl/role'
import type { Records, RoleData, MenuList } from '@/api/acl/role/type'
// 引入骨架的仓库
import useLayOutSettingStore from '@/store/modules/setting'
import { ElMessage } from 'element-plus';
// 创建仓库
let layOutSettingStore = useLayOutSettingStore()
// 当前页码
let pageNo = ref<number>(1)
// 每页显示数据条数
let pageSize = ref<number>(10)
// 数据总条数
let total = ref<number>(0)
// 搜索职位关键字
let keyword = ref<string>('')
// 存储全部职位数据的数组
let allRoleArr = ref<Records>([])
// 控制对话框的显示与隐藏
let dialogVisible = ref<boolean>(false)
// 收集新增岗位的数据
let roleParams = reactive<RoleData>({
   roleName: ''
})
// 获取表单实例
let form = ref()
// 控制抽屉组件的显示与隐藏
let drawer = ref<boolean>(false)
// 存储用户权限的数据
let menuArr = ref<MenuList>([])
// 准备一个数组：用于存储最后一层节点勾选的id
let selectArr = ref<number[]>([])
// 获取树形控件的实例
let tree = ref()
// 树形控件默认展示数据
const defaultProps = {
   children: 'children',
   label: 'name'
}
// 获取全部职位数据|分页器当前页码发生变化的回调
const getAllRole = async (pager = 1) => {
   // 修改当前页码
   pageNo.value = pager
   let result = await reqAllRoleList(pageNo.value, pageSize.value, keyword.value)
   if (result.code == 200) {
      // 存储数据
      allRoleArr.value = result.data.records
      total.value = result.data.total
   }
}
// 分页器下拉菜单change事件的回调
const sizeChange = () => {
   getAllRole()
}
// 搜索按钮的回调
const search = () => {
   // 根据关键字再次发送请求
   getAllRole()
   // 清空关键字
   keyword.value = ''
}
// 重置按钮的回调
const reset = () => {
   layOutSettingStore.refresh = !layOutSettingStore.refresh
}
// 添加职位按钮的回调
const addRole = () => {
   dialogVisible.value = true
   // 清空数据
   Object.assign(roleParams, {
      roleName: '',
      id: 0
   })
   // 清空上一次表单校验的提示信息
   nextTick(() => {
      form.value.clearValidate('roleName')
   })
}
// 编辑职位按钮的回调
const updateRole = (row: RoleData) => {
   dialogVisible.value = true
   // 存储已有的职位信息
   Object.assign(roleParams, row)
   // 清空上一次表单校验的提示信息
   nextTick(() => {
      form.value.clearValidate('roleName')
   })
}
// 组件挂载完毕
onMounted(() => {
   getAllRole()
})
// roleName的自定义校验规则
const validateRoleName = (rule: any, value: any, callBack: any) => {
   if (value.trim().length >= 2) {
      callBack()
   } else {
      callBack(new Error('职位名称的长度至少二位！'))
   }
}
// 职位信息表单的校验规则
const rules = {
   roleName: [
      { required: true, trigger: 'blur', validator: validateRoleName }
   ]
}
// dialog确定按钮的回调
const save = async () => {
   // 表单校验通过再发请求
   await form.value.validate()
   let result = await reqAddOrUpdateRole(roleParams)
   if (result.code == 200) {
      ElMessage.success(roleParams.id ? '更新成功！' : '添加成功！')
      dialogVisible.value = false
      getAllRole(roleParams.id ? pageNo.value : 1)
   } else {
      ElMessage.error(roleParams.id ? '更新失败！' : '添加失败！')
      dialogVisible.value = false
   }
}
// 分配权限按钮的回调
const setPermission = async (row: RoleData) => {
   drawer.value = true
   // 收集当前要设置权限的职位的数据
   Object.assign(roleParams, row)
   // 根据当前职位获取对应权限的数据
   let result = await reqAllMenuList((roleParams.id as number))
   if (result.code == 200) {
      menuArr.value = result.data
      selectArr.value = filterSelectArr(menuArr.value, [])
   }
}
const filterSelectArr = (allData: any, initArr: any) => {
   allData.forEach((item: any) => {
      if (item.children && item.children.length > 0) {
         filterSelectArr(item.children, initArr)
      } else {
         if (item.select) {
            initArr.push(item.id)
         }
      }
   })
   return initArr
}
// drawer确定按钮的回调
const confirm = async () => {
   // 职位的id
   const roleId = (roleParams.id as number)
   // 选中节点的id
   let arr = tree.value.getCheckedKeys()
   // 半选节点的id
   let arr1 = tree.value.getHalfCheckedKeys()
   let permissionId = arr.concat(arr1)
   let result = await reqSetPermission(roleId, permissionId)
   if (result.code == 200) {
      drawer.value = false
      ElMessage.success('分配权限成功！')
      // 页面刷新
      window.location.reload()
   } else {
      drawer.value = false
      ElMessage.error('权限分配失败！')
   }
}
// 气泡确认框确定按钮的回调
const deleteRole = async (id: number) => {
   let result = await reqDeleteRole(id)
   if (result.code == 200) {
      ElMessage.success('删除成功！')
      // 重新获取数据
      getAllRole(allRoleArr.value.length > 1 ? pageNo.value : pageNo.value - 1)
   }
}
</script>

<style lang="scss" scoped>
.form {
   display: flex;
   justify-content: space-between;
   align-items: center;
}
</style>